package worker

import (
	"distributed/conf"
	"distributed/message"
	"fmt"
	"log"
	"math/rand"
	"net/rpc"
	"time"
)

type RpcClient struct {
	client *rpc.Client
}

func (r *RpcClient) Ready(method string) message.ReptileReq {
	rand.Seed(time.Now().UnixNano())
	time.Sleep(time.Millisecond * 100 * time.Duration(rand.Int63n(10)+10))
	//fmt.Println()
	req := message.ReptileReq{
		URL:    conf.GetConfig("worker_url"),
		Method: method,
	}
	var resp message.ReptileResp
	if err := r.client.Call("Worker.Ready", req, &resp); err != nil {
		panic(err)
	}
	fmt.Printf("[ Ready resp ]\n")
	//fmt.Printf("[ Ready request ] request: %#v\n[ Ready result ] result: %#v\n", result)
	return req
}

func (r *RpcClient) pullResult() *message.ReptileReq {
	var request message.ReptileReq
	if err := r.client.Call("Worker.PullTask", message.ReptileReq{}, &request); err != nil {
		fmt.Printf("[ pushResult ] error: %v\n", err)
		shutDown(err)
		return nil
	}
	return &request
}

func (r *RpcClient) pushResult(request message.ReptileResult) {
	var result message.ReptileResp
	if err := r.client.Call("Worker.Receiver", request, &result); err != nil {
		fmt.Printf("[ pushResult ] error: %v\n", err)
		shutDown(err)
		return
	}
}

func shutDown(err error) {
	if err == rpc.ErrShutdown {
		log.Fatalf("[ shutDown ] error: %v\n", err)
	}
}

var client *RpcClient

func RpcConnect() {
	var err error
	client = &RpcClient{}
	client.client, err = rpc.DialHTTP("tcp", conf.GetConfig("server_url"))
	if err != nil {
		//fmt.Printf("[ RpcConnect ] error: %v\n", err)
		//time.Sleep(time.Second)
		panic(err)
	}
}
